Baked-in Laziness
Earlier in this course, we talked about producers and consumers. As a quick refresher, this is a mental model that distinguishes between two different kinds of work:
- Producing is the act of building something that developers will use to build products. For example, we might build a generic
Button
component. - Consuming is the act of using that thing. For example, sprinkling the
Button
component all over the application, creating the actual UI that users will use.
Over the past couple of lessons, we've been looking at how to implement lazy-loading, and we've been thinking about it exclusively from the consumer perspective. When we want to use a component — whether it's a third-party component like react-latex-next
or a custom component we produced — we swap out the import:
// From this...import HeavyComponent from '@/components/HeavyComponent';
// ...to this:const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'));
This places the burden on the consumer. If we use HeavyComponent
10 different times in our app, we have to remember to use the alternative import()
syntax each and every time.
Instead, I prefer to “bake in” the lazy loading on the producer side. That way, we guarantee that the component will always be lazy-loaded, without the consumer needing to do anything special.
Let's talk about how to do this, for our react-latex-next
package.
Creating a component wrapper
So, the immediate problem is that we aren't actually the producer of the react-latex-next
package. We didn't create it, it's not our code.
We'll solve for that by building our own thin wrapper around this package:
// src/components/Latex.jsimport Spinner from '@/components/Spinner';
const LazyLatex = dynamic( () => import('react-latex-next'), { loading: Spinner });
function Latex({ children, ...delegated }) { return ( <LazyLatex {...delegated}> {children} </LazyLatex> );}
export default Latex;
This new Latex
component is a thin wrapper around react-latex-next
. We forward all of the props along, so that it can be used exactly the same as the underlying third-party component.
When we need to format some LaTeX, we'll import this new component, using a standard import:
import Latex from '@/components/Latex';
By creating this thin wrapper around the react-latex-next
package, we've taken on the mantle of “producer”. This new Latex
component is our own creation, and we can use it to lock in whatever we want. In this case, we've implemented a full lazy-loading setup, including the loading indicator.
We've removed the burden from the consumer. When we're in “consumer mode”, we don't have to do anything special to get all the benefits of lazy loading. It's baked in.
Pretty cool, right? 😄